package com.ecommerce.product.domain;

import com.ecommerce.product.enums.ProductType;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.Document;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * SpEL 表达式解析：框架会解析 #{@indexNameResolver.resolveIndexName(#this)}，其中：
 * #this 表示当前 ProductDocument 实例
 * 调用 indexNameResolver.resolveIndexName(document) 方法动态获取索引名
 */

/**
 * 商品文档实体类，对应Elasticsearch中的文档结构
 * 使用@Document注解定义索引相关配置
 */
@Builder
@Data
@Document(
        indexName = "#{@indexNameResolver.resolveIndexName(#this)}", // 动态索引名
        //或者：indexName = "#{@indexNameResolver.resolveIndexName(#this.productType)}"
        createIndex = false// 不自动创建索引
)
public class ProductDocument {

    /**
     * 商品唯一标识符
     * 使用@Id注解标记为文档主键
     * @Id 注解标记：框架会读取被 @Id 注解修饰的字段值作为文档 ID
     */
    @Id
    private Long id;

    /**
     * 商品名称
     * 使用ik_max_word分词器进行中文分词
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String name;

    /**
     * 商品编码
     * 使用Keyword类型表示不分词
     */
    @Field(type = FieldType.Keyword)
    private String code;

    /**
     * 价格，用于计算，scaled_float 型。
     * 通过scaling_factor将小数转换为长整型存储,完全保留精度，无精度损失，支持范围查询和聚合计算，存储效率高于text+keyword，
     * 不使用double，因为double存在浮点数精度问题，不适用于财务等高精度场景。
     * 合理设置scaling_factor：货币：100（2位小数），科学计算：1000（3位小数），加密货币：1e8（8位小数）。
     * 聚合计算需要启用doc_values。
     * 自动忽略格式错误数据：ignoreMalformed = true
     */
    @Field(type = FieldType.Scaled_Float, scalingFactor = 100, docValues = true, ignoreMalformed = true)
    private BigDecimal price;

    /**
     * 价格，用于精确展示，keyword 型。
     * 金融/电商系统：必选 scaled_float + keyword 双字段。
     */
    @Field(type = FieldType.Keyword)
    private String priceExact;

    /**
     * 商品库存数量
     */
    @Field(type = FieldType.Integer)
    private Integer stock;

    /**
     * 商品类型枚举
     */
    @Field(type = FieldType.Keyword)
    private ProductType productType;

    /**
     * 商品状态
     * 1-上架 0-下架
     */
    @Field(type = FieldType.Integer)
    private Integer status; // 1-上架 0-下架

    // 其他字段...

    /**
     * 商品创建时间
     * 使用date_hour_minute_second格式存储
     */
    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
    private Date createTime;

    /**
     * 商品最后更新时间
     * 使用date_hour_minute_second格式存储
     */
    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
    private Date updateTime;

    /**
     * 一级分类ID
     */
    @Field(type = FieldType.Long)
    private Long categoryId;

    /**
     * 一级分类名称
     * 使用ik_max_word分词器进行中文分词
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String categoryName;

    /**
     * 二级分类ID
     */
    @Field(type = FieldType.Long)
    private Long subCategoryId;

    /**
     * 二级分类名称
     * 使用ik_max_word分词器进行中文分词
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String subCategoryName;

    /**
     * 商品主图URL
     * 使用Keyword类型表示不分词
     */
    @Field(type = FieldType.Keyword)
    private String mainImage;

    /**
     * 商品描述
     * 使用ik_max_word分词器进行中文分词
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String description;

    /**
     * 商品规格参数列表
     * 使用Nested类型表示嵌套文档
     */
    @Field(type = FieldType.Nested)
    private List<Spec> specs;

    /**
     * 商品规格内部类
     */
    @Data
    public static class Spec {
        /**
         * 规格名称
         */
        @Field(type = FieldType.Keyword)
        private String key;

        /**
         * 规格值
         */
        @Field(type = FieldType.Keyword)
        private String value;
    }
}